{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1Pi_B2cvdBiW"
      },
      "source": [
        "##### Copyright 2018 The TF-Agents Authors."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "nQnmcm0oI1Q-"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3NFuTvWVZG_B"
      },
      "source": [
        "# ポリシー\n",
        "\n",
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td><a target=\"_blank\" href=\"https://www.tensorflow.org/agents/tutorials/3_policies_tutorial\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\"> TensorFlow.orgで表示</a></td>\n",
        "  <td><a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs-l10n/blob/master/site/ja/agents/tutorials/3_policies_tutorial.ipynb\">     <img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\">Google Colabで実行</a></td>\n",
        "  <td><a target=\"_blank\" href=\"https://github.com/tensorflow/docs-l10n/blob/master/site/ja/agents/tutorials/3_policies_tutorial.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\">GitHub でソースを表示{</a></td>\n",
        "  <td><a href=\"https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/ja/agents/tutorials/3_policies_tutorial.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\">ノートブックをダウンロード/a0}</a></td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "31uij8nIo5bG"
      },
      "source": [
        "## はじめに"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PqFn7q5bs3BF"
      },
      "source": [
        "強化学習では、ポリシーは環境からの観察を行動または行動の分布にマッピングします。TF-Agent では、環境からの観測は、名前付きタプル`TimeStep('step_type', 'discount', 'reward', 'observation')`に含まれています。また、ポリシーはタイムステップを行動または行動の分布にマップします。ほとんどのポリシーは`timestep.observation`を使用し、一部のポリシーは`timestep.step_type`を使用します（ステートフルポリシーのエピソードの開始時に状態をリセットする場合など）。`timestep.discount`および`timestep.reward`は通常無視されます。\n",
        "\n",
        "ポリシーは、TF-Agent の他のコンポーネントと次のように関連しています。ほとんどのポリシーには、行動や TimeStep からの行動の分布を計算するニューラルネットワークがあります。エージェントには、デプロイするためにトレーニングされた主要なポリシーやデータ収集のためのノイジーなポリシーなど、さまざまな目的のために複数のポリシーを含めることができます。ポリシーは保存/復元でき、エージェントとは関係なくデータ収集、評価などに使用できます。\n",
        "\n",
        "Tensorflow で記述しやすいポリシーもあれば（ニューラルネットワークを使用するポリシーなど）、Python で記述しやすいポリシーもあります（行動のスクリプトに従う場合など）。そのため、TF Agent では、Python と Tensorflow の両方のポリシーが許可されています。さらに、TensorFlow で記述されたポリシーを Python 環境で使用する必要がある場合や、逆にトレーニングに TensorFlow ポリシーを使用し、後で Python の本番環境にデプロイすることが必要な場合もあります。これを簡単に実行するために、Python と TensorFlow ポリシー間を変換するラッパーが提供されています。\n",
        "\n",
        "ポリシーのもう 1 つの興味深いクラスは、特定のポリシーを特定の方法で変更するポリシーラッパーです。例えば特定のタイプのノイズを追加し、確率的ポリシーの greedy または epsilon-greedy バージョンを作成したり、複数のポリシーをランダムに混合できます。 "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HdnG_TT_amWH"
      },
      "source": [
        "## セットアップ"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9Meq2nT_aquh"
      },
      "source": [
        "TF-agent をまだインストールしていない場合は、次を実行します。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "xsLTHlVdiZP3"
      },
      "outputs": [],
      "source": [
        "!pip install tf-agents"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "sdvop99JlYSM"
      },
      "outputs": [],
      "source": [
        "from __future__ import absolute_import\n",
        "from __future__ import division\n",
        "from __future__ import print_function\n",
        "\n",
        "import abc\n",
        "import tensorflow as tf\n",
        "import tensorflow_probability as tfp\n",
        "import numpy as np\n",
        "\n",
        "from tf_agents.specs import array_spec\n",
        "from tf_agents.specs import tensor_spec\n",
        "from tf_agents.networks import network\n",
        "\n",
        "from tf_agents.policies import py_policy\n",
        "from tf_agents.policies import random_py_policy\n",
        "from tf_agents.policies import scripted_py_policy\n",
        "\n",
        "from tf_agents.policies import tf_policy\n",
        "from tf_agents.policies import random_tf_policy\n",
        "from tf_agents.policies import actor_policy\n",
        "from tf_agents.policies import q_policy\n",
        "from tf_agents.policies import greedy_policy\n",
        "\n",
        "from tf_agents.trajectories import time_step as ts\n",
        "\n",
        "tf.compat.v1.enable_v2_behavior()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NyXO5-Aalb-6"
      },
      "source": [
        "## Python ポリシー"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DOtUZ1hs02bu"
      },
      "source": [
        "Python ポリシーのインターフェースは、`policies/py_policy.PyPolicy`で定義されています。主なメソッドは次のとおりです。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "4PqNEVls1uqc"
      },
      "outputs": [],
      "source": [
        "class Base(object):\n",
        "\n",
        "  @abc.abstractmethod\n",
        "  def __init__(self, time_step_spec, action_spec, policy_state_spec=()):\n",
        "    self._time_step_spec = time_step_spec\n",
        "    self._action_spec = action_spec\n",
        "    self._policy_state_spec = policy_state_spec\n",
        "\n",
        "  @abc.abstractmethod\n",
        "  def reset(self, policy_state=()):\n",
        "    # return initial_policy_state.\n",
        "    pass\n",
        "\n",
        "  @abc.abstractmethod\n",
        "  def action(self, time_step, policy_state=()):\n",
        "    # return a PolicyStep(action, state, info) named tuple.\n",
        "    pass\n",
        "\n",
        "  @abc.abstractmethod\n",
        "  def distribution(self, time_step, policy_state=()):\n",
        "    # Not implemented in python, only for TF policies.\n",
        "    pass\n",
        "\n",
        "  @abc.abstractmethod\n",
        "  def update(self, policy):\n",
        "    # update self to be similar to the input `policy`.\n",
        "    pass\n",
        "\n",
        "  @property\n",
        "  def time_step_spec(self):\n",
        "    return self._time_step_spec\n",
        "\n",
        "  @property\n",
        "  def action_spec(self):\n",
        "    return self._action_spec\n",
        "\n",
        "  @property\n",
        "  def policy_state_spec(self):\n",
        "    return self._policy_state_spec"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "16kyDKk65bka"
      },
      "source": [
        "最も重要なメソッドは`action(time_step)`で、環境からの観測を含む`time_step`を、次の属性を含む PolicyStep という名前のタプルにマップします。\n",
        "\n",
        "- `action`：環境に適用される行動。\n",
        "- `state`：次の行動の呼び出しにフィードされるポリシーの状態（RNN 状態など）。\n",
        "- `info`：行動のログ確率などのオプションの補足情報。\n",
        "\n",
        "`time_step_spec`および`action_spec`は、入力されたタイムステップと出力された行動の仕様です。ポリシーには`reset`関数もあり、通常、ステートフルポリシーの状態をリセットするために使用されます。`update(new_policy)`関数は`self`を`new_policy`に向けて更新します。\n",
        "\n",
        "それでは、Python ポリシーの例をいくつか見てみましょう。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YCH1Hs_WlmDT"
      },
      "source": [
        "### 例1：ランダムPythonポリシー"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lbnQ0BQ3_0N2"
      },
      "source": [
        "`PyPolicy`の簡単な例は、`RandomPyPolicy`で、指定された個別/連続する action_spec に対してランダムな行動を生成します。入力`time_step`は無視されます。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "QX8M4Nl-_0uu"
      },
      "outputs": [],
      "source": [
        "action_spec = array_spec.BoundedArraySpec((2,), np.int32, -10, 10)\n",
        "my_random_py_policy = random_py_policy.RandomPyPolicy(time_step_spec=None,\n",
        "    action_spec=action_spec)\n",
        "time_step = None\n",
        "action_step = my_random_py_policy.action(time_step)\n",
        "print(action_step)\n",
        "action_step = my_random_py_policy.action(time_step)\n",
        "print(action_step)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "B8WrFOR1lz31"
      },
      "source": [
        "### 例2：スクリプト化されたPythonポリシー"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AJ0Br1lGBnTT"
      },
      "source": [
        "スクリプト化されたポリシーは、`(num_repeats, action)`タプルのリストとして表される行動のスクリプトを再生します。`action`関数が呼び出されるたびに、指定された繰り返し回数が完了するまでリストから次の行動が返され、リスト内の次の行動に移動します。リストの先頭から実行するには`reset`メソッドを呼び出します。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "_mZ244m4BUYv"
      },
      "outputs": [],
      "source": [
        "action_spec = array_spec.BoundedArraySpec((2,), np.int32, -10, 10)\n",
        "action_script = [(1, np.array([5, 2], dtype=np.int32)), \n",
        "                 (0, np.array([0, 0], dtype=np.int32)), # Setting `num_repeats` to 0 will skip this action.\n",
        "                 (2, np.array([1, 2], dtype=np.int32)), \n",
        "                 (1, np.array([3, 4], dtype=np.int32))]\n",
        "\n",
        "my_scripted_py_policy = scripted_py_policy.ScriptedPyPolicy(\n",
        "    time_step_spec=None, action_spec=action_spec, action_script=action_script)\n",
        "\n",
        "policy_state = my_scripted_py_policy.get_initial_state()\n",
        "time_step = None\n",
        "print('Executing scripted policy...')\n",
        "action_step = my_scripted_py_policy.action(time_step, policy_state)\n",
        "print(action_step)\n",
        "action_step= my_scripted_py_policy.action(time_step, action_step.state)\n",
        "print(action_step)\n",
        "action_step = my_scripted_py_policy.action(time_step, action_step.state)\n",
        "print(action_step)\n",
        "\n",
        "print('Resetting my_scripted_py_policy...')\n",
        "policy_state = my_scripted_py_policy.get_initial_state()\n",
        "action_step = my_scripted_py_policy.action(time_step, policy_state)\n",
        "print(action_step)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3Dz7HSTZl6aU"
      },
      "source": [
        "## TensorFlow ポリシー"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LwcoBXqKl8Yb"
      },
      "source": [
        "TensorFlow ポリシーは、Python ポリシーと同じインターフェースに従います。いくつかの例を見てみましょう。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3x8pDWEFrQ5C"
      },
      "source": [
        "### 例1：ランダム TF ポリシー\n",
        "\n",
        "RandomTFPolicy を使用すると、指定された離散/連続`action_spec`に従ってランダムな行動を生成できます。入力`time_step`は、無視されます。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "nZ3pe5G4rjrW"
      },
      "outputs": [],
      "source": [
        "action_spec = tensor_spec.BoundedTensorSpec(\n",
        "    (2,), tf.float32, minimum=-1, maximum=3)\n",
        "input_tensor_spec = tensor_spec.TensorSpec((2,), tf.float32)\n",
        "time_step_spec = ts.time_step_spec(input_tensor_spec)\n",
        "\n",
        "my_random_tf_policy = random_tf_policy.RandomTFPolicy(\n",
        "    action_spec=action_spec, time_step_spec=time_step_spec)\n",
        "observation = tf.ones(time_step_spec.observation.shape)\n",
        "time_step = ts.restart(observation)\n",
        "action_step = my_random_tf_policy.action(time_step)\n",
        "\n",
        "print('Action:')\n",
        "print(action_step.action)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "GOBoWETprWCB"
      },
      "source": [
        "### 例2：アクターポリシー\n",
        "\n",
        "アクターポリシーは、`time_steps`を行動にマップするネットワーク、または、`time_steps`を行動上の分布にマップするネットワークのいずれかを使用して作成できます。\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2S94E5zQgge_"
      },
      "source": [
        "#### 行動ネットワークの使用"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "X2LM5STNgv1u"
      },
      "source": [
        "次のようにネットワークを定義します。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "S2wFgzJFteQX"
      },
      "outputs": [],
      "source": [
        "class ActionNet(network.Network):\n",
        "\n",
        "  def __init__(self, input_tensor_spec, output_tensor_spec):\n",
        "    super(ActionNet, self).__init__(\n",
        "        input_tensor_spec=input_tensor_spec,\n",
        "        state_spec=(),\n",
        "        name='ActionNet')\n",
        "    self._output_tensor_spec = output_tensor_spec\n",
        "    self._sub_layers = [\n",
        "        tf.keras.layers.Dense(\n",
        "            action_spec.shape.num_elements(), activation=tf.nn.tanh),\n",
        "    ]\n",
        "\n",
        "  def call(self, observations, step_type, network_state):\n",
        "    del step_type\n",
        "\n",
        "    output = tf.cast(observations, dtype=tf.float32)\n",
        "    for layer in self._sub_layers:\n",
        "      output = layer(output)\n",
        "    actions = tf.reshape(output, [-1] + self._output_tensor_spec.shape.as_list())\n",
        "\n",
        "    # Scale and shift actions to the correct range if necessary.\n",
        "    return actions, network_state"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "k7fIn-ybVdC6"
      },
      "source": [
        "TensorFlow では、ほとんどのネットワークレイヤーがバッチ処理用に設計されているため、入力 time_steps がバッチ処理され、ネットワークの出力もバッチ処理されることが想定されています。また、ネットワークは、指定された action_spec の正常な範囲で行動を生成する役割を担います。これは慣習的に[-1, 1] で行動を生成する最終レイヤーに tanh アクティベーションなどを使用し、それを入力 action_spec として正常な範囲にスケーリングとシフトを行うことで実現されます。（`tf_agents/agents/ddpg/networks.actor_network()`を参照してください。）\n",
        "\n",
        "上記のネットワークを使用してアクターポリシーを作成できます。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "0UGmFTe7a5VQ"
      },
      "outputs": [],
      "source": [
        "input_tensor_spec = tensor_spec.TensorSpec((4,), tf.float32)\n",
        "time_step_spec = ts.time_step_spec(input_tensor_spec)\n",
        "action_spec = tensor_spec.BoundedTensorSpec((3,),\n",
        "                                            tf.float32,\n",
        "                                            minimum=-1,\n",
        "                                            maximum=1)\n",
        "\n",
        "action_net = ActionNet(input_tensor_spec, action_spec)\n",
        "\n",
        "my_actor_policy = actor_policy.ActorPolicy(\n",
        "    time_step_spec=time_step_spec,\n",
        "    action_spec=action_spec,\n",
        "    actor_network=action_net)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xlmGPTAmfPK3"
      },
      "source": [
        "これは、time_step_spec に続く time_steps のバッチに適用できます。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "fvsIsR0VfOA4"
      },
      "outputs": [],
      "source": [
        "batch_size = 2\n",
        "observations = tf.ones([2] + time_step_spec.observation.shape.as_list())\n",
        "\n",
        "time_step = ts.restart(observations, batch_size)\n",
        "\n",
        "action_step = my_actor_policy.action(time_step)\n",
        "print('Action:')\n",
        "print(action_step.action)\n",
        "\n",
        "distribution_step = my_actor_policy.distribution(time_step)\n",
        "print('Action distribution:')\n",
        "print(distribution_step.action)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lumtyhejZOXR"
      },
      "source": [
        "上記の例では、行動テンソルを生成する行動ネットワークを使用してポリシーを作成しました。この場合、`policy.distribution(time_step)`は、`policy.action(time_step)`の出力に関する確定的（デルタ）分布です。確率的ポリシーを作成するには、行動にノイズを追加するポリシーラッパーでアクターポリシーをラップします。また、以下のように、行動ネットワークの代わりに行動分布ネットワークを使用してアクターポリシーを作成することもできます。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_eNrJ5gKgl3W"
      },
      "source": [
        "#### 行動分布ネットワークの使用"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "sSYzC9LobVsK"
      },
      "outputs": [],
      "source": [
        "class ActionDistributionNet(ActionNet):\n",
        "\n",
        "  def call(self, observations, step_type, network_state):\n",
        "    action_means, network_state = super(ActionDistributionNet, self).call(\n",
        "        observations, step_type, network_state)\n",
        "\n",
        "    action_std = tf.ones_like(action_means)\n",
        "    return tfp.distributions.Normal(action_means, action_std), network_state\n",
        "\n",
        "\n",
        "action_distribution_net = ActionDistributionNet(input_tensor_spec, action_spec)\n",
        "\n",
        "my_actor_policy = actor_policy.ActorPolicy(\n",
        "    time_step_spec=time_step_spec,\n",
        "    action_spec=action_spec,\n",
        "    actor_network=action_distribution_net)\n",
        "\n",
        "action_step = my_actor_policy.action(time_step)\n",
        "print('Action:')\n",
        "print(action_step.action)\n",
        "distribution_step = my_actor_policy.distribution(time_step)\n",
        "print('Action distribution:')\n",
        "print(distribution_step.action)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "BzoNGJnlibtz"
      },
      "source": [
        "上記では、行動は指定された行動仕様[-1, 1]の範囲にクリップされていることに注意してください。これは、デフォルトで ActorPolicy clip=True のコンストラクタ引数があるためです。これをfalseに設定すると、ネットワークにより生成されたクリップされていない行動が返されます。 "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PLj6A-5domNG"
      },
      "source": [
        "たとえば、`stochastic_policy.distribution().mode()`を行動として選択する GreedyPolicy ラッパーと、この greedy な行動に関する確定的/デルタ分布をその`distribution()`として使用することにより、確率的ポリシーは、確定的ポリシーに変換できます。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4Xxzo2a7rZ7v"
      },
      "source": [
        "### 例3：Q ポリシー"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "79eGLqpOhQVp"
      },
      "source": [
        "Q ポリシーは、DQN などのエージェントで使用されるポリシーで、個別の行動ごとにQ値を予測する Q ネットワークに基づいています。特定のタイムステップで、Q ポリシーの行動分布は q 値をロジットとして使用して作成されたカテゴリカル分布です。\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Haakr2VvjqKC"
      },
      "outputs": [],
      "source": [
        "input_tensor_spec = tensor_spec.TensorSpec((4,), tf.float32)\n",
        "time_step_spec = ts.time_step_spec(input_tensor_spec)\n",
        "action_spec = tensor_spec.BoundedTensorSpec((),\n",
        "                                            tf.int32,\n",
        "                                            minimum=0,\n",
        "                                            maximum=2)\n",
        "num_actions = action_spec.maximum - action_spec.minimum + 1\n",
        "\n",
        "\n",
        "class QNetwork(network.Network):\n",
        "\n",
        "  def __init__(self, input_tensor_spec, action_spec, num_actions=num_actions, name=None):\n",
        "    super(QNetwork, self).__init__(\n",
        "        input_tensor_spec=input_tensor_spec,\n",
        "        state_spec=(),\n",
        "        name=name)\n",
        "    self._sub_layers = [\n",
        "        tf.keras.layers.Dense(num_actions),\n",
        "    ]\n",
        "\n",
        "  def call(self, inputs, step_type=None, network_state=()):\n",
        "    del step_type\n",
        "    inputs = tf.cast(inputs, tf.float32)\n",
        "    for layer in self._sub_layers:\n",
        "      inputs = layer(inputs)\n",
        "    return inputs, network_state\n",
        "\n",
        "\n",
        "batch_size = 2\n",
        "observation = tf.ones([batch_size] + time_step_spec.observation.shape.as_list())\n",
        "time_steps = ts.restart(observation, batch_size=batch_size)\n",
        "\n",
        "my_q_network = QNetwork(\n",
        "    input_tensor_spec=input_tensor_spec,\n",
        "    action_spec=action_spec)\n",
        "my_q_policy = q_policy.QPolicy(\n",
        "    time_step_spec, action_spec, q_network=my_q_network)\n",
        "action_step = my_q_policy.action(time_steps)\n",
        "distribution_step = my_q_policy.distribution(time_steps)\n",
        "\n",
        "print('Action:')\n",
        "print(action_step.action)\n",
        "\n",
        "print('Action distribution:')\n",
        "print(distribution_step.action)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Xpu9m6mvqJY-"
      },
      "source": [
        "## ポリシーラッパー"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OfaUrqRAoigk"
      },
      "source": [
        "ポリシーラッパーは、特定のポリシーをラップして変更するために使用できます（ノイズを追加する場合など）。ポリシーラッパーはポリシー（Python / TensorFlow）のサブクラスであるため、他のポリシーと同じように使用できます。 "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-JJVVAALqVNQ"
      },
      "source": [
        "### 例：Greedy ポリシー\n",
        "\n",
        "greedyラッパーは、`distribution()`を実装する TensorFlow ポリシーをラップするために使用できます。`GreedyPolicy.action()`は`wrapped_policy.distribution().mode()`を返し、`GreedyPolicy.distribution()`は`GreedyPolicy.action()`の確定的/デルタ分布です。"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "xsRPBeLZtXvu"
      },
      "outputs": [],
      "source": [
        "my_greedy_policy = greedy_policy.GreedyPolicy(my_q_policy)\n",
        "\n",
        "action_step = my_greedy_policy.action(time_steps)\n",
        "print('Action:')\n",
        "print(action_step.action)\n",
        "\n",
        "distribution_step = my_greedy_policy.distribution(time_steps)\n",
        "print('Action distribution:')\n",
        "print(distribution_step.action)"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [],
      "name": "3_policies_tutorial.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
